﻿using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;
using System.Collections.Generic;
using System;

namespace UnityEngine.UI
{
    public abstract class TreeNodeContainer : UIBehaviour
    {
        private GameObject m_goCached;
        public GameObject GoCached
        {
            get
            {
                if(!m_goCached)
                {
                    m_goCached = gameObject;
                }
                return m_goCached;
            }
        }

        private RectTransform m_transCached;
        public RectTransform TransCached
        {
            get
            {
                if(!m_transCached)
                {
                    m_transCached = GetComponent<RectTransform>();
                }
                return m_transCached;
            }
        }

        public abstract RectTransform ContainerRoot
        {
            get;
        }

        public abstract TreeView OwnerView
        {
            get;
        }

        /// <summary>
        /// 子节点列表 
        /// </summary>
        private SortedList<TreeNode, byte> m_childList;
        public SortedList<TreeNode, byte> ChildList
        {
            get
            {
                return m_childList;
            }
        }

        public int ChildCount
        {
            get
            {
                return m_childList != null ? m_childList.Count : 0;
            }
        }

        public bool HasChild
        {
            get
            {
                return m_childList != null && m_childList.Count > 0;
            }
        }

        public TreeNode AddChildNode()
        {
            TreeNode node = GenerateTreeNode(ContainerRoot);
            if(node != null)
            {
                AddNodeToList(node);
            }
            return node;
        }

        public TreeNode InsertChildNodeAt(int index)
        {
            if(index > ChildCount)
            {
                throw new ArgumentOutOfRangeException();
            }
            if(index == ChildCount)
            {
                return AddChildNode();
            }
            TreeNode node = GenerateTreeNode(ContainerRoot);
            if(node != null)
            {
                TreeNode targetNode = m_childList.Keys[index];
                if(targetNode != null)
                {
                    node.TransCached.SetSiblingIndex(targetNode.TransCached.GetSiblingIndex());
                }
                AddNodeToList(node);
            }
            return node;
        }

        public void RemoveChildNodeAt(int index)
        {
            if(index >= ChildCount)
            {
                throw new ArgumentOutOfRangeException();
            }
            TreeNode node = m_childList.Keys[index];
            RemoveNodeFromList(node, index);
            Destroy(node.GoCached);
        }

        public void RemoveChildNode(TreeNode node)
        {
            int index = m_childList.IndexOfKey(node);
            if(index != -1)
            {
                RemoveNodeFromList(node, index);
                Destroy(node.GoCached);
            }
        }

        protected virtual void AddNodeToList(TreeNode node)
        {
            if(m_childList == null)
            {
                m_childList = new SortedList<TreeNode, byte>(OwnerView);
            }
            m_childList.Add(node, 0);
        }

        protected virtual void RemoveNodeFromList(TreeNode node, int index)
        {
            m_childList.RemoveAt(index);
        }

        /// <summary>
        /// 清空节点
        /// </summary>
        public void ClearNodes()
        {
            if(m_childList != null && m_childList.Count > 0)
            {
                foreach(var item in m_childList.Keys)
                {
                    Destroy(item.GoCached);
                }
                m_childList.Clear();
            }
        }


        /// <summary>
        /// 生成节点
        /// </summary>
        /// <returns></returns>
        public TreeNode GenerateTreeNode(RectTransform transParent)
        {
            var ownerView = OwnerView;
            if(ownerView && ownerView.TemplateNode)
            {
                GameObject goNode = Instantiate(ownerView.TemplateNode.GoCached);
                var node = goNode.GetComponent<TreeNode>();
                node.TransCached.SetParent(transParent, false);
                node.OnGenerate();
                if(node != null)
                {
                    node.SetOwnerView(ownerView);
                }
                return node;
            }
            return null;
        }
    }
}
